package main

import (
	"embed"
	"flag"
	"fmt"
	"io/fs"
	"net/http"
	"os"
	"strconv"
	"time"

	"gitee.com/liumou_site/logger"
	"gitee.com/liumou_site/network-troubleshooting/route"
	"github.com/gin-gonic/gin"
)

//go:embed static/*
var staticFiles embed.FS

// main函数是程序的入口点。
func main() {
	// 解析命令行参数
	port := flag.Int("p", 8095, "指定服务监听端口")
	addr := flag.String("a", "0.0.0.0", "指定服务监听地址")
	version := flag.Bool("v", false, "显示版本信息")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "网络诊断工具\n")
		fmt.Fprintf(os.Stderr, "作者: liumou_site\n")
		fmt.Fprintf(os.Stderr, "项目主页: https://gitee.com/liumou_site/network-troubleshooting\n\n")
		fmt.Fprintf(os.Stderr, "用法:\n")
		flag.PrintDefaults()
	}
	flag.Parse()
	if *version {
		logger.Info("当前版本: 1.1.1")
		os.Exit(0)
	}

	// 初始化gin框架的默认引擎。
	r := gin.Default()

	// 设置静态文件服务
	staticFS, err := fs.Sub(staticFiles, "static")
	if err != nil {
		logger.Error("无法加载静态文件:", err)
		return
	}
	r.StaticFS("static", http.FS(staticFS))

	// 配置根路径的GET请求处理函数，返回index.html文件。
	r.GET("/", func(c *gin.Context) {
		file, err := staticFiles.ReadFile("static/index.html")
		if err != nil {
			c.String(http.StatusInternalServerError, "无法加载首页")
			return
		}
		c.Data(http.StatusOK, "text/html; charset=utf-8", file)
	})

	// 进行路由的检查，确保路由配置的正确性。
	route.Check()
	// 解析路由配置，动态加载路由。
	route.Parse(r)

	// 配置/ping路径的GET请求处理函数，用于检测服务状态。
	r.GET("/ping", route.PingHandler)
	// 配置/traceroute路径的GET请求处理函数，用于执行 traceroute 功能。
	r.GET("/traceroute", route.TracerouteHandler)
	// 配置/tcptraceroute路径的GET请求处理函数
	r.GET("/tcptraceroute", route.TcpTracerouteHandler)
	// 配置/stream路径的GET请求处理函数，用于实时输出
	r.GET("/stream", func(c *gin.Context) {
		c.Header("Content-Type", "text/event-stream")
		c.Header("Cache-Control", "no-cache")
		c.Header("Connection", "keep-alive")

		for i := 0; i < 10; i++ {
			fmt.Fprintf(c.Writer, "data: Message %d\n\n", i)
			c.Writer.Flush()
			time.Sleep(1 * time.Second)
		}
	})

	listened := *addr + ":" + strconv.Itoa(*port)
	// 启动HTTP服务，监听指定端口
	err = r.Run(listened)
	if err != nil {
		logger.Error("启动HTTP服务失败:", err)
		return
	}
}
